package com.atguigu.tingshu.live.api;

import com.alibaba.fastjson.JSON;
import com.atguigu.tingshu.common.constant.RedisConstant;
import com.atguigu.tingshu.live.util.WebSocketLocalContainerUtil;
import com.atguigu.tingshu.model.live.FromUser;
import com.atguigu.tingshu.model.live.SocketMsg;
import com.atguigu.tingshu.model.user.UserInfo;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.websocket.*;
import jakarta.websocket.server.PathParam;
import jakarta.websocket.server.ServerEndpoint;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

@Slf4j
@Tag(name = "直播间即时通讯接口管理")
@ServerEndpoint(value = "/api/websocket/{liveRoomId}/{token}")
@Component
public class WebSocketApiController {

    /**
     * 连接建立成功调用的方法
     */
    private static RedisTemplate<String , String> redisTemplate ;

    @Autowired
    private void setRedisTemplate(RedisTemplate<String , String> redisTemplate) {
        WebSocketApiController.redisTemplate = redisTemplate ;
    }

    // 连接建立成功调用的方法
    @OnOpen
    public void onOpen(Session session, @PathParam("liveRoomId") Long liveRoomId, @PathParam("token") String token) {

        log.info("建立连接，liveRoomId：{}， token：{}", liveRoomId, token);

        //从redis获取用户基本信息，登录时保存到了redis
        String userInfoJSON = redisTemplate.opsForValue().get(RedisConstant.USER_LOGIN_KEY_PREFIX + token);
        UserInfo userInfo = JSON.parseObject(userInfoJSON, UserInfo.class);
        Long userId = userInfo.getId();

        //构建即时通讯用户基本信息
        FromUser fromUser = new FromUser();
        fromUser.setUserId(userInfo.getId());
        fromUser.setNickname(userInfo.getNickname());
        fromUser.setAvatarUrl(userInfo.getAvatarUrl());

        //保存用户与直播间关联关系到容器
        WebSocketLocalContainerUtil.addSession(userId, session);
        WebSocketLocalContainerUtil.addFromUser(userId, fromUser);
        WebSocketLocalContainerUtil.addUserIdToLiveRoom(liveRoomId, userId);

        //构建消息：加入直播间
        SocketMsg socketMsg = WebSocketLocalContainerUtil.buildSocketMsg(liveRoomId,
                fromUser, SocketMsg.MsgTypeEnum.JOIN_CHAT,
                fromUser.getNickname() + "加入直播间");
        WebSocketLocalContainerUtil.sendMsg(socketMsg);

    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose(Session session, @PathParam("liveRoomId") Long liveRoomId, @PathParam("token") String token) {
        log.info("断开连接，liveRoomId：{}， token：{}", liveRoomId, token);

        //从redis获取用户基本信息，登录时保存到了redis
        String userInfoJSON = redisTemplate.opsForValue().get(RedisConstant.USER_LOGIN_KEY_PREFIX + token);
        UserInfo userInfo = JSON.parseObject(userInfoJSON, UserInfo.class);
        Long userId = userInfo.getId();

        //构建消息：退出直播间
        FromUser fromUser = WebSocketLocalContainerUtil.getFromUser(userId);
        SocketMsg socketMsg = WebSocketLocalContainerUtil.buildSocketMsg(liveRoomId,
                fromUser,
                SocketMsg.MsgTypeEnum.CLOSE_SOCKET,
                fromUser.getNickname()+"离开直播间");

        //删除容器中的关联关系
        WebSocketLocalContainerUtil.removeSession(userId);
        WebSocketLocalContainerUtil.removeFromUser(userId);
        WebSocketLocalContainerUtil.removeUserIdToLiveRoom(liveRoomId, userId);

        // 发送从直播间退出消息
        WebSocketLocalContainerUtil.sendMsg(socketMsg);    }

    /**
     * 收到客户端消息后调用的方法
     *
     * @param message 客户端发送过来的消息
     */
    @OnMessage
    public void onMessage(String message, Session session) {
        log.info("来自客户端的消息：{}", message);
        //        SocketMsg socketMsg = JSON.parseObject(message, SocketMsg.class);
        //        WebSocketLocalContainerUtil.sendMsg(socketMsg);
        //redis广播
        redisTemplate.convertAndSend("message:list", message);
    }

    /**
     * 发生错误时调用+
     */
    @OnError
    public void onError(Session session, Throwable error) {
        log.error("发生错误");
        error.printStackTrace();
    }

}